package com.ycj.lockcache.lock;

import com.ycj.lockcache.enums.LockType;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author changjin.yuan
 * @Date 2019/9/2 14:42
 */

@Component
public class DistributedLockImpl implements DistributedLock {

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public RLock lock(String lockKey, long timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, TimeUnit.SECONDS);
        return lock;
    }

    @Override
    public RLock lock(String lockKey, LockType lockType, long timeout) {
        RLock lock = null;
        if (lockType.equals(LockType.REENTRANT_LOCK)) {
            lock = redissonClient.getLock(lockKey);
        } else if (lockType.equals(LockType.READ_LOCK)) {
            lock = redissonClient.getReadWriteLock(lockKey).readLock();
        } else if (lockType.equals(LockType.WRITE_lOCK)) {
            lock = redissonClient.getReadWriteLock(lockKey).writeLock();
        } else if (lockType.equals(LockType.FAIR_LOCK)) {
            lock = redissonClient.getFairLock(lockKey);
        }
        lock.lock(timeout, TimeUnit.SECONDS);
        return lock;

    }

    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        if (Objects.nonNull(lock)) {
            lock.unlock();
        }
    }

    @Override
    public void unlock(RLock lock) {
        lock.unlock();
    }
}
